import { Events } from './Events'



/**
 * 计算动画渲染帧率
 *
 * @class FPS
 */
class FPS {
    constructor() {
        this.ele = document.createElement('div');
        this.ele.classList = ['FPS'];
        this.catch = [];
        document.body.appendChild(this.ele);
        this.lastTime = 0;
    }

    /**
     * 添加帧率计算
     * 
     * @param {Number} num
     * @memberof FPS
     */
    push(num) {
        // console.log(num);
        var time = num - this.lastTime;
        this.lastTime = num;
        this.catch.push(time);
        var fps = 0;
        eval('fps = ' + this.catch.join("+"));
        if (fps > 1000) {
            this.ele.innerText = 'FPS : ' + this.catch.length;
            this.catch = [];
        };
    }
}


/**
 * 动画引擎
 *
 * @class EngineEvent
 * @extends {Events}
 */
class EngineEvent extends Events {
    constructor(options) {
        super();
        /**
         * 引擎配置参数
         * @memberof EngineEvent
         */
        this.options = Object.assign({}, options);
        /**
         * canvas 实体
         * @memberof EngineEvent
         */
        this.canvas = document.createElement('canvas');
        this.canvas.id = "Engine";
        this.ctx = this.canvas.getContext("2d");
        this.reSize();
        window.onresize = () => {
            this.reSize();
        }
        /**
         * 帧率计算对象
         * @memberof EngineEvent
         */
        this.FPS = new FPS();
        /**
         * 帧数计数缓存
         * @memberof EngineEvent
         */
        this.index = 0;

        this.player = [];
        this.playerBullets = [];
        this.enemy = [];
        this.enemyBullets = [];
    }
    /**
     * 根据 屏幕宽高，绘制canvas 大小
     *
     * @memberof EngineEvent
     */
    reSize() {
        let _windowWidth = document.body.clientWidth;
        let _windowHeight = document.body.clientHeight;
        this.options.width = this.options.width || 1080;
        this.options.height = this.options.height || 1920;
        this.scale = 1;
        if (this.options.width > this.options.height) {
            this.scale = this.options.height / this.options.width;
            this.realWidth = _windowWidth;
            this.realHeight = _windowWidth * this.scale;
        } else {
            this.scale = this.options.width / this.options.height;
            this.realHeight = _windowHeight;
            this.realWidth = _windowHeight * this.scale;
        }
        this.canvas.width = this.realWidth;
        this.canvas.height = this.realHeight;
    }
    /**
     * 初始化
     *
     * @memberof EngineEvent
     */
    init() {
        document.body.appendChild(this.canvas);
        this.start(0)
    }
    /**
     * 开始动画递归执行
     *
     * @memberof EngineEvent
     */
    start(num) {
        this.loop();
        this.FPS.push(num);
        requestAnimationFrame((num) => {
            this.start(num);
        });
    }
    /**
     * 渲染对象
     *
     * @param {String} type 渲染对象类型
     * @memberof EngineEvent
     */
    render(type) {
        this[type].forEach(element => {
            this.ctx.save();
            element.draw(this.ctx);
        });
    }
    /**
     * 执行动画渲染事件
     *
     * @param {*} index
     * @memberof EngineEvent
     */
    loop() {
        var c = this.ctx;
        if (!c) return;
        c.clearRect(0, 0, this.canvas.width, this.canvas.height);
        ['player', 'enemy', 'playerBullets', 'enemyBullets'].forEach(ele => {
            this.render(ele);
        })
    }
    /**
     * 添加可渲染对象
     *
     * @param {Object} obj 可渲染对象
     * @param {String} type 渲染类型
     * @return {Blob} 是否正确添加
     * @memberof EngineEvent
     */
    addObject(obj, type) {
        let _obj = this[type];
        if (!_obj) return false;
        // if (obj.setDrawEvent) obj.setDrawEvent(this);
        _obj.push(obj);
        return true
    }
    /**
     * 删除可渲染对象
     *
     * @param {Object} obj 可渲染对象
     * @param {String} type 渲染类型
     * @return {Blob} 是否正确删除
     * @memberof EngineEvent
     */
    removeObject(obj, type) {
        let _obj = this[type];
        if (!_obj) return false;
        let isRemove = false;
        for (let i = 0; i < _obj.length; i++) {
            const element = _obj[i];
            if (element === obj) {
                _obj.splice(i, 1);
                isRemove = true;
                break;
            }
        }
        return isRemove;
    }
}

var Engine = new EngineEvent();

export { Engine }